package ai.turbochain.ipex.config;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import ai.turbochain.ipex.ext.OrdinalToEnumConverterFactory;
import ai.turbochain.ipex.interceptor.MemberInterceptor;

/**
 * @author jack
 * @date 2018年02月06日
 * @see 重命名 corsFilter 解决与 Spring Security 冲突的问题
 */
@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter {

	/**
	 * 国际化
	 *
	 * @return
	 */
	@Bean(name = "messageSource")
	public ResourceBundleMessageSource getMessageSource() {
		ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
		resourceBundleMessageSource.setDefaultEncoding("UTF-8");
		resourceBundleMessageSource.setBasenames("i18n/messages", "i18n/ValidationMessages");
		resourceBundleMessageSource.setCacheSeconds(3600);
		return resourceBundleMessageSource;
	}

	// 使用自定义的LocaleResolver来替换掉默认的LocaleResolver
	@Bean
	public LocaleResolver localeResolver() {
		return new MyLocaleResolver();
	}

	@Override
	public Validator getValidator() {
		LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
		validator.setValidationMessageSource(getMessageSource());
		return validator;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/asset/**").addResourceLocations("classpath:/asset/");
		super.addResourceHandlers(registry);
	}

	@Override
	public void addFormatters(FormatterRegistry registry) {
		registry.addConverterFactory(new OrdinalToEnumConverterFactory());
		super.addFormatters(registry);
	}

	/**
	 * 添加拦截器
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(getMemberInterceptor()).addPathPatterns("/**").excludePathPatterns("/register/**",
				"/mobile/code", "/email/code", "/email/login/code", "/email/reset/code", "/getKaptchaImage", "/login",
				"/check", "/check/login", "/start/captcha", "/support/country", "/ancillary/**", "/announcement/**",
				"/mobile/reset/code", "/reset/email/code", "/mobile-register/email", "/mobile-register/reset-password",
				"/mobile-exange/asset/wallet/**", "/mobile-exange/asset/quick-pay", "/reset/login/password",
				"/vote/info", "/coin/supported", "/financial/items/**", "/coin/guess/index", "/coin/guess/record",
				"/hard-id/saveNone", "/hard-id/reset-password", "/coin/guess/detail", "/coin/cny-rate/**",
				"/coin/guess/type");

		super.addInterceptors(registry);
	}

	@Bean
	public FilterRegistrationBean corsFilterForBusi() {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		CorsConfiguration config = new CorsConfiguration();
		config.addAllowedOrigin("*");
		config.setAllowCredentials(true);
		config.addAllowedHeader("*");
		config.addAllowedMethod("*");
		config.addExposedHeader("x-auth-token");
		source.registerCorsConfiguration("/**", config);
		FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
		bean.setOrder(0);
		return bean;
	}

	/**
	 * 这里需要先将限流拦截器入住，不然无法获取到拦截器中的redistemplate
	 * 
	 * @return
	 */
	@Bean
	public MemberInterceptor getMemberInterceptor() {
		return new MemberInterceptor();
	}

}